
import * as THREE from 'three';
import CarWheels from './carWheels'
import CarLights from './carLigths'
/*
***** Car hierarchy（车辆层级） *****
CarWhole
├── wheelFL
├── wheelFR
├── wheelBL
├── wheelBR
├── CarChassis 车辆底盘
    ├── BodyBlack
    ├── BodySilver
    ├── Brakes 刹车
    ├── FFBack
    ├── GlassTinted 挡光玻璃
    ├── GlassTransparent 透明玻璃
    ├── Headlights 头灯
    ├── Taillights 尾灯
    └── Undercarriage 起落架

For lens flare, look into:
https://alteredqualia.com/three/examples/webgl_city.html
*/
export default class CarBody {
    constructor(_scene, _cargo) {
        console.log('车体信息类')
        this.parent = _scene;
        this.carWhole = new THREE.Group();
        this.carWhole.rotateY(-Math.PI / 2);
        this.parent.add(this.carWhole);
        this.carChassis = this.buildCarChassis(_cargo["vrBodyCompiled"], _cargo["envReflection"]);
        this.carWhole.add(this.carChassis);
        this.addShadow(_cargo["shadow"]);
        this.carLights = new CarLights(this.carChassis, _cargo);
        this.carWheels = new CarWheels(this.carWhole, _cargo);
    }
    // Creates black part of body 创建车身
    buildCarChassis (_bodyGeom, _cubeText) {
        _bodyGeom.scale.set(0.0005, 0.0005, 0.0005);
        _bodyGeom.position.set(1.56, 0, 0);
        // 环境反光贴图
        this.envCube = _cubeText;
        this.envCube.format = THREE.RGBFormat;
        // Material Body Color
        this.matBodySilver = new THREE.MeshStandardMaterial({
            color: 0xbbbbbb,
            metalness: 0.7,
            roughness: 0.7,
            envMap: this.envCube,
        });
        // Workaround for browsers without Texture LevelOfDetail support
        if (window["EXT_STLOD_SUPPORT"] === false) {
            this.envCube.minFilter = THREE.LinearFilter;
            this.matBodySilver.metalness = 0.05;
            this.matBodySilver.roughness = 0.8;
            this.matBodySilver.color = new THREE.Color(0x777777);
        }
        // Material Body Black
        this.matBodyBlack = new THREE.MeshLambertMaterial({
            color: 0x000000,
            emissive: 0x444444,
            reflectivity: 0.8,
            envMap: this.envCube,
        });
        // Tinted windows
        this.matGlassTinted = new THREE.MeshLambertMaterial({
            color: 0x000000,
            emissive: 0x666666,
            reflectivity: 1,
            envMap: this.envCube,
        });
        this.matUndercarriage = new THREE.MeshBasicMaterial({
            color: 0x000000
        });
        // Transparent glass
        this.matGlassTransp = new THREE.MeshLambertMaterial({
            color: 0x000000,
            emissive: 0x666666,
            reflectivity: 1.0,
            envMap: this.envCube,
            transparent: true,
            blending: THREE.AdditiveBlending,
        });
        // Car bodymaterials 车身材料
        _bodyGeom.getObjectByName("BodyBlack").material = this.matBodyBlack;
        _bodyGeom.getObjectByName("BodySilver").material = this.matBodySilver;
        _bodyGeom.getObjectByName("GlassTransparent").material = this.matGlassTransp;
        _bodyGeom.getObjectByName("GlassTinted").material = this.matGlassTinted;
        _bodyGeom.getObjectByName("Undercarriage").material = this.matUndercarriage;
        return _bodyGeom;
    };
    addShadow (_shad) {
        var shadowPlane = new THREE.PlaneBufferGeometry(6.5, 6.5, 1, 1);
        shadowPlane.rotateX(-Math.PI / 2);
        shadowPlane.translate(1.56, 0, 0);
        var shadowMat = new THREE.MeshBasicMaterial({
            map: _shad,
            side: THREE.DoubleSide,
            blending: THREE.MultiplyBlending,
            transparent: true,
            depthWrite: false
        });
        var shadowMesh = new THREE.Mesh(shadowPlane, shadowMat);
        this.carWhole.add(shadowMesh);
    };
    ///////////////////////////// PUBLIC METHODS /////////////////////////////
    onWindowResize (_vpH) {
        this.carLights.onWindowResize(_vpH);
    };
    // Called once per frame
    update (_props) {
        // Apply car physics
        this.carWhole.rotation.y = _props.theta;
        this.carChassis.rotation.z = _props.longitMomentum * 0.0015;
        this.carChassis.rotation.x = _props.lateralMomentum * 0.002;
        this.carWheels.update(_props);
        this.carLights.update(_props);
    };
}